using System;
using JK.EventRouter.Eventing;

namespace JK.EventRouter.WorkItems
{
    /// <summary>An implementation of IWorkItem that allows a callback after the work has been completed.</summary>
    public abstract class CompletableWorkItem<T> : ICompletableWorkItem where T : class
    {
        private readonly IAction<T> _onComplete;
        private T _onCompleteArg = null;

        /// <summary>
        /// Depending on the implementation of IAction, work may be processed on a background thread <see cref="GuiThreadAction{T}"/> 
        /// OR marshalled to the gui thread <see cref="BackgroundThreadAction{T}"/> 
        /// </summary>
        public CompletableWorkItem(IAction<T> onComplete)
        {
            if (onComplete == null) { throw new ArgumentNullException("onComplete"); }
            _onComplete = onComplete;
        }

        public bool CanComplete
        {
            get { return _onCompleteArg != null; }
        }

        /// <summary>An interface only method used by the <see cref="EventRouter"/>to invoke the callback</summary>
        /// <remarks>This method is purposely hidden to prevent accidental invocation by anyone other than EventRouter</remarks>
        void ICompletableWorkItem.OnComplete()
        {
            if (_onCompleteArg == null) { throw new Exception("Completion arguments have not been set"); }
            _onComplete.Act(_onCompleteArg);
        }

        /// <summary>Set the appropriate data for use in the callback operation</summary>
        public void SetOnCompleteArg(T arg)
        {
            _onCompleteArg = arg;
        }

    }
}